package modeling;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;


/**
 * @author Mathieu Rousseau
 * @email mathieu.rousseau3@mail.mcgill.ca
 */


/*  start of HiCtoIF class  */
public class HiCtoIF {


	/*  global variables  */
	private static final String inputPath = "HiCtoIF/Input/";
	private static final String outputPath = "HiCtoIF/Output/";
	private static String filename = "default_filename.txt";
	private static int numberOfBins = 0;
	private static double[][] HiCvalues;
	private static int count = 3;
	/*  end of global variables  */


	/*  start of getNumberOfBins method  */
	private static void getNumberOfBins(){		
		//  read in the file and count the number of bins
		String line = null;
		String labels = null;
		try{
			BufferedReader br = new BufferedReader(new FileReader(inputPath + filename));			

			boolean doneHeader = false;			//  there is one header line to skip
			boolean doneLabels = false;			//  there is one line with the labels to skip

			while((line = br.readLine()) != null){
				if(doneHeader){
					if(doneLabels){
						numberOfBins++;
					}
					else{
						//						System.out.println(line);
						labels = line;
						doneLabels = true;
					}
				}
				else{
					//					System.out.println(line);
					doneHeader = true;
				}
			}
			br.close();
		}catch (IOException e) {
			e.printStackTrace();
		}
	}/*  end of getNumberOfBins method  */


	/*  start of getHiCvalues method  */
	private static void getHiCvalues(){		
		//  read in the file and count the number of bins
		int rowCounter = 0;
		String line = null;
		try{
			BufferedReader br = new BufferedReader(new FileReader(inputPath + filename));			

			boolean doneHeader = false;			//  there is one header line to skip
			boolean doneLabels = false;			//  there is one line with the labels to skip

			while((line = br.readLine()) != null){
				if(doneHeader){
					if(doneLabels){
						String[] values = line.split("\t");
						//  the first entry is the label, need to skip it and start at index 1
						for(int i=1; i<values.length; i++){
							HiCvalues[rowCounter][i-1] = Double.parseDouble(values[i]);
						}
						rowCounter++;
					}
					else{
						//						System.out.println(line);						
						doneLabels = true;
					}
				}
				else{
					//					System.out.println(line);
					doneHeader = true;
				}
			}
			br.close();
		}catch (IOException e) {
			e.printStackTrace();
		}
		if(rowCounter != numberOfBins){
			System.out.println("Error getting the HiC data: the rowCounter (" + rowCounter + ") does not equal the number of bins (" +
					numberOfBins + ").\nSystem.exit(0)");
			System.exit(0);
		}
	}/*  end of getHiCvalues method  */


	/*  start of checkSymmetry method  */
	private static void checkSymmetry(){
		for(int i=0; i<numberOfBins; i++){
			for(int j=i; j<numberOfBins; j++){
				if(i == j){
					if(HiCvalues[i][j] != 0.0){
						System.out.println("Error:\tHiCvalues[" + i + "][" + j + "] does not equal zero (0), it equals " + HiCvalues[i][j]);
						System.out.println("\tSetting HiCvalues[" + i + "][" + j + "] to zero (0)");
					}
				}
				else if(i < j){
					if(HiCvalues[i][j] != HiCvalues[j][i]){
						System.out.println("Error: the matrix is not symmetric.");
						System.out.println("HiCvalues[" + i + "][" + j + "] (" + HiCvalues[i][j] +
								") does not equal HiCvalues[" + j + "][" + i + "] (" + HiCvalues[j][i] + ")"); 
						System.out.println("System.exit(0)");
						System.exit(0);
					}
				}
			}
		}

	}/*  end of checkSymmetry method  */


	/*  start of printHiCvalues method  */
	private static void printHiCvalues(){
		for(int i=0; i<HiCvalues.length; i++){
			for(int j=0; j<HiCvalues.length; j++){
				System.out.print(HiCvalues[i][j] + "\t");
			}
			System.out.println();
		}
	}/*  end of printHiCvalues method  */


	/*  start of outputIFvalues method  */
	private static void outputIFvalues(){
		String outputFilename = "LIST_output_" + filename;
		try{						
			BufferedWriter bw = new BufferedWriter(new FileWriter(outputPath + outputFilename));
			
			Random random = new Random();
			
			for(int i=0; i<numberOfBins-1; i++){
				for(int j=i+1; j<numberOfBins; j++){
					
					bw.write((i+1) + "\t" + (j+1) + "\t" + HiCvalues[i][j] + "\t" + (10+Math.sqrt(HiCvalues[i][j])) + "\t" + count);
					
//					if(HiCvalues[i][j] < 20){
//						bw.write((i+1) + "\t" + (j+1) + "\t" + HiCvalues[i][j] + "\t" + (((1.0 + HiCvalues[i][j]) / 1.25) + (random.nextDouble() * 0.1)) + "\t" + count);
//					}
//					else if(HiCvalues[i][j] < 100){
//						bw.write((i+1) + "\t" + (j+1) + "\t" + HiCvalues[i][j] + "\t" + (((1.0 + HiCvalues[i][j]) / 2.0) + (random.nextDouble() * 0.1)) + "\t" + count);
//					}
//					else{
//						bw.write((i+1) + "\t" + (j+1) + "\t" + HiCvalues[i][j] + "\t" + (((1.0 + HiCvalues[i][j]) / 10.0) + (random.nextDouble() * 0.1)) + "\t" + count);
//					}
					if(!((i == numberOfBins-2) && (j == numberOfBins-1))){
						bw.newLine();
						bw.flush();
					}
				}
			}
			
			

//			for(int i=0; i<numberOfBins-1; i++){
//				for(int j=i+1; j<numberOfBins; j++){
//					if(HiCvalues[i][j] < 20){
//						bw.write((i+1) + "\t" + (j+1) + "\t" + HiCvalues[i][j] + "\t" + (((1.0 + HiCvalues[i][j]) / 1.25) + (random.nextDouble() * 0.1)) + "\t" + count);
//					}
//					else if(HiCvalues[i][j] < 100){
//						bw.write((i+1) + "\t" + (j+1) + "\t" + HiCvalues[i][j] + "\t" + (((1.0 + HiCvalues[i][j]) / 2.0) + (random.nextDouble() * 0.1)) + "\t" + count);
//					}
//					else{
//						bw.write((i+1) + "\t" + (j+1) + "\t" + HiCvalues[i][j] + "\t" + (((1.0 + HiCvalues[i][j]) / 10.0) + (random.nextDouble() * 0.1)) + "\t" + count);
//					}
//					if(!((i == numberOfBins-2) && (j == numberOfBins-1))){
//						bw.newLine();
//						bw.flush();
//					}
//				}
//			}
			
			
			bw.flush();
			bw.close();
		}catch (IOException e) {
			e.printStackTrace();
		}//end of try-catch block
		System.out.println("Output file: " + outputFilename);
	}/*  end of outputIFvalues method  */


	/*  start of main method  */
	public static void main(String[] args) {
//		filename = "HIC_chr19_chr19_100000_obs_no_centromere.txt";
		filename = "HiC_gm06690_chr14_chr14_1000000_obs_no_centromere.txt";
		

		getNumberOfBins();
		HiCvalues = new double[numberOfBins][numberOfBins];
		System.out.println("number of bins = " + numberOfBins);

		getHiCvalues();

		checkSymmetry();

		//		printHiCvalues();

		System.out.println("Using a chosen set count value of " + count);
		outputIFvalues();

	}/*  end of main method  */

}/*  end of HiCtoIF class  */
